﻿using System;
using System.Net.Sockets;
using System.Text;
using System.Net;
using System.Threading;
using System.Collections.Generic;


namespace testCSEchoServer
{
	class MainClass
	{
		private static List<string> messages = new List<string>();

		private static void SendThread(List<TcpClient> connections)
		{
			while (true)
			{
				string str = null;
				lock(messages)
				{
					if (messages.Count > 0)
					{
						str = messages[0];
						messages.RemoveAt(0);
					}
				}
				if (str != null)
				{
					var buff = Encoding.ASCII.GetBytes(str);
					lock(connections)
					{
						foreach (var c in connections)
						{
							try
							{
								//c.Send(buff);
								c.GetStream().Write(buff, 0, buff.Length);
							}
							catch (Exception exp)
							{
								Console.WriteLine(exp.ToString());
							}
						}
					}
				}
				Thread.Sleep(100);
			}
		}


		private static async void ProcessSocket(TcpClient client)
		{
			var stream = client.GetStream();

			while (true)
			{
				Console.WriteLine("Before receive");
				var buffer = new byte[1024];
				var n = 0;
				try
				{
					n = await stream.ReadAsync(buffer, 0, 1024);
				}
				catch (Exception exp)
				{
					Console.WriteLine(exp.ToString());
				}
				Console.WriteLine("Server Receive: " + n);

				if (n == 0)
				{
					try
					{
						client.Close();
					}
					catch (Exception exp)
					{
						Console.WriteLine(exp.ToString());
					}

					lock (connections)
					{
						connections.Remove(client);
					}
					break;
				}

				lock (messages)
				{
					var str = Encoding.ASCII.GetString(buffer, 0, n);
					messages.Add(str);
				}
			}
		}

		private static void AsyncClient(TcpClient client)
		{
			ProcessSocket(client);
		}


		private static List<TcpClient> connections = new List<TcpClient>();
		public static void Main(string[] args)
		{
			//BUild SOcket
			//Listen
			//Receive
			//Send

			var listener = new TcpListener( 4040);
			listener.Start();

			var sendThread = new Thread(() =>
			{
				SendThread(connections);
			});
			sendThread.Start();

			while (true)
			{
				Console.WriteLine("Before Accept");
				var client = listener.AcceptTcpClient();
				lock(connections)
				{
					connections.Add(client);
				}

				AsyncClient(client);
			}
		}
	}
}
